package com.service.sale;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import com.alibaba.excel.EasyExcel;
import com.common.StringUtils;
import com.common.easyui.EasyuiUtils;
import com.common.http.HttpResult;
import com.common.http.HttpStatus;
import com.common.model.Global;
import com.common.spring.SpringMvcUtils;
import com.dao.sale.ContractDraftDao;
import com.dao.sale.ContractSignDao;
import com.dao.sale.ProductDao;
import com.dao.sale.SkuItemDao;
import com.dao.sys.MmDao;
import com.dao.sys.SysUserRoleMapper;
import com.enums.BtnDbPermissionEnum;
import com.enums.WorkFlowIdModel;
import com.model.external.oa.OaWorkFlowResult;
import com.model.sale.ContractDraftModel;
import com.model.sale.ContractSignModel;
import com.model.sale.ContractVOModel;
import com.model.sale.ProductModel;
import com.model.sale.SkuItemModel;
import com.model.sys.MmModel;
import com.model.sys.SysDict;
import com.model.sys.SysUser;
import com.service.external.oa.CreateSaleContractService;
import com.service.external.oa.GetWFStatusService;
import com.service.sys.SysDictService;

@Service
public class ContractDraftService {
	static final Logger logger = LoggerFactory.getLogger(ContractDraftService.class);

	@Autowired
	ContractDraftDao contractDraftDao;
	@Autowired
	ContractSignDao contractSignDao;
	@Autowired
	ProductDao productDao;
	@Autowired
	CreateSaleContractService createSaleContractService;
	@Autowired
	GetWFStatusService wfStatusService;

	@Autowired
	SkuItemDao skuItemDao;
	@Autowired
	SysUserRoleMapper sysUserRoleMapper;

	@Autowired
	MmDao mmDao;

	/**
	 * 列表查询
	 *
	 * @param queryMap
	 * @return
	 */
	public HttpResult selectList(Map<String, Object> queryMap) {
		HttpResult httpResult = new HttpResult();
		EasyuiUtils.addPageNum(queryMap);
		EasyuiUtils.addFilter(queryMap);
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (!sysUser.getSuperadmin().equals(Global.YES + "")) {
			if (StringUtils.isNotNull(sysUser.getDatapermission())) {
				queryMap.put("deptIds", sysUser.getDatapermission().split(","));
			} else {
				if (sysUser.getBtnPermission() != null
						&& sysUser.getBtnPermission().contains(BtnDbPermissionEnum.sale.getValue())) {
					// 销售管理员
				} else if (sysUser.getBtnPermission() != null
						&& sysUser.getBtnPermission().contains(BtnDbPermissionEnum.BatteryChemical.getValue())) {
					// 锂电池管理员
					queryMap.put("draOrgName", BtnDbPermissionEnum.BatteryChemical.getName());
					queryMap.put("dracreateId", sysUser.getUserid());
				} else if (sysUser.getBtnPermission() != null
						&& sysUser.getBtnPermission().contains(BtnDbPermissionEnum.FineChemical.getValue())) {
					// 精细管理员
					queryMap.put("draOrgName", BtnDbPermissionEnum.FineChemical.getName());
					queryMap.put("dracreateId", sysUser.getUserid());
				} else if (StringUtils.isNotNull(sysUser.getDatapermission())) {
					// 销售部门权限
					queryMap.put("deptIds", sysUser.getDatapermission().split(","));
				} else {
					queryMap.put("createId", sysUser.getUserid());
				}
			}
		}
		List<ContractDraftModel> list = contractDraftDao.selectList(queryMap);
		int count = contractDraftDao.selectListCount(queryMap);
		httpResult.setRows(list);
		httpResult.setTotal(count);
		logger.info("selectList:{}", list);
		return httpResult;
	}

	/**
	 * 详情
	 *
	 * @param
	 * @return
	 */
	public HttpResult selectInfor(String draId) {
		HttpResult httpResult = new HttpResult();
		ContractVOModel contractVOModel = contractDraftDao.load(draId);
		if (contractVOModel != null) {
			HashMap<String, Object> hashMap = new HashMap<String, Object>();
			hashMap.put("draId", draId);
			List<ProductModel> productModels = productDao.selectList(hashMap);
			contractVOModel.setProductModels(productModels);
		}
		httpResult.setData(contractVOModel);
		httpResult.setCode(HttpStatus.SUCCESS_CODE);
		return httpResult;
	}

	@Autowired
	SysDictService sysDictService;

	// 修改运费计算模式
	@Transactional
	public HttpResult updateMode(String draId) {
		if (draId == null) {
			return HttpResult.error("参数不能为空");
		}
		HttpResult httpResult = new HttpResult();
		int result = 0;
		ContractVOModel contractVOModel = new ContractVOModel();
		contractVOModel.setDraId(draId);
		contractVOModel.setDraIsIn(Global.YES + "");
		result = contractDraftDao.update(contractVOModel);

		if (result > 0) {
			httpResult.setMsg("保存成功!");
//			httpResult.setData(contractVOModel);
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("保存失败!");
		}
		return httpResult;
	}

	/**
	 * 保存
	 *
	 * @param
	 * @return
	 * @Tran
	 */
	@Transactional
	public HttpResult save(ContractVOModel contractVOModel) {
		if (contractVOModel == null) {
			return HttpResult.error("参数不能为空");
		}
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (!StringUtils.isNotNull(sysUser.getSap())) {
			return HttpResult.error("sap用户id不能为空!");
		}

		HashMap<String, Object> dicHashMap = new HashMap<String, Object>();
		dicHashMap.put("dicValue", contractVOModel.getDraAddress());
		List<SysDict> dicts = sysDictService.selectDictListByParams(dicHashMap);
		if (dicts == null || dicts.size() == 0) {
			return HttpResult.error("请从下拉框选择到货地址!");
		}

		HttpResult httpResult = new HttpResult();
		int result = 0;
		contractVOModel.setTransedSap("0");

		if (contractVOModel.getStatus().equals(Global.YES + "")) {
			// 调用oa接口
			HttpResult oaResult = createSaleContractService.CreateContract(contractVOModel, sysUser.getWxid());

			if (oaResult.getCode() != HttpStatus.SUCCESS_CODE) {
				// 强制手动事务回滚
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return HttpResult.error(oaResult.getMsg());
			} else {
				OaWorkFlowResult oaWorkFlowResult = (OaWorkFlowResult) oaResult.getData();
				contractVOModel.setOaWfId(oaWorkFlowResult.getOaFlowId());
			}
		}
		if (!StringUtils.isNotNull(contractVOModel.getDraId())) {
			contractVOModel.setDraId(UUID.randomUUID().toString());
			// 新增时设置合同编号
			contractVOModel.setDraCode(createDraftSerialNumber());
			result = contractDraftDao.insert(contractVOModel);
		} else {
			result = contractDraftDao.update(contractVOModel);
		}

		List<ProductModel> productModels = contractVOModel.getProductModels();
		// 虚拟合同显示履行明细行数=1
		if ((Global.YES + "").equals(contractVOModel.getDraVirtual())) {
			if (!CollectionUtils.isEmpty(productModels) && productModels.size() > 1) {
				return HttpResult.error("虚拟合同履行明细总行数不得大于1!");
			}
		}
		if (productModels != null) {
			productDao.deleteByDraId(contractVOModel.getDraId());
			for (int i = 0; i < productModels.size(); i++) {
				ProductModel productModel = productModels.get(i);
				// 设置项目行号
				String number = productModel.getLineNumber();
				if (StringUtils.isNullOrEmpty(number)) {
					number = String.valueOf((i + 1) * 10);
				}
				productModel.setLineNumber(number);
				// 计算皮重
				BigDecimal tare = getProductTare(productModel);
				productModel.setTare(tare);
				productModel.setProId(UUID.randomUUID().toString());
				productModel.setDraId(contractVOModel.getDraId());
				productModel.setStatus(contractVOModel.getStatus());
				productDao.insert(productModel);
			}
		}
		if (result > 0) {
			httpResult.setMsg(contractVOModel.getStatus().equals(Global.YES + "") ? "提交成功!" : "保存成功!");
			httpResult.setData(contractVOModel);
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg(contractVOModel.getStatus().equals(Global.YES + "") ? "提交失败!" : "保存失败!");
		}
		return httpResult;
	}

	/**
	 * 长约合同保存
	 *
	 * @param
	 * @return
	 * @Tran
	 */
	@Transactional
	public HttpResult saveLongTerm(ContractVOModel contractVOModel) {
		if (contractVOModel == null) {
			return HttpResult.error("参数不能为空");
		}
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (!StringUtils.isNotNull(sysUser.getSap())) {
			return HttpResult.error("sap用户id不能为空!");
		}
		HttpResult httpResult = new HttpResult();
		int result = 0;
		contractVOModel.setTransedSap("0");

		if (contractVOModel.getStatus().equals(Global.YES + "")) {
			// 调用oa接口
			HttpResult oaResult = createSaleContractService.CreateLongTermContract(contractVOModel, sysUser.getWxid());

			if (oaResult.getCode() != HttpStatus.SUCCESS_CODE) {
				// 强制手动事务回滚
				TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
				return HttpResult.error(oaResult.getMsg());
			} else {
				OaWorkFlowResult oaWorkFlowResult = (OaWorkFlowResult) oaResult.getData();
				contractVOModel.setOaWfId(oaWorkFlowResult.getOaFlowId());
			}
		}
		if (!StringUtils.isNotNull(contractVOModel.getDraId())) {
			// 根据原虚拟合同id，查询该虚拟合同是否已转为长约合同
			String oldDraCode = contractVOModel.getOldDraCode();
			ContractVOModel oldVirtualContract = contractDraftDao.selectByOldDraCode(oldDraCode);
			if (null != oldVirtualContract) {
				return HttpResult
						.error("合同号为 " + oldDraCode + "虚拟合同已转为长约合同，长约合同号 " + oldVirtualContract.getDraCode() + "!");
			}
			contractVOModel.setDraId(UUID.randomUUID().toString());
			// 新增时设置合同编号
			contractVOModel.setDraCode(createDraftSerialNumber());
			result = contractDraftDao.insert(contractVOModel);
		} else {
			result = contractDraftDao.update(contractVOModel);
		}

		List<ProductModel> productModels = contractVOModel.getProductModels();
		if (productModels != null) {
			productDao.deleteByDraId(contractVOModel.getDraId());
			for (int i = 0; i < productModels.size(); i++) {
				ProductModel productModel = productModels.get(i);
				// 设置项目行号
				String number = productModel.getLineNumber();
				if (StringUtils.isNullOrEmpty(number)) {
					number = String.valueOf((i + 1) * 10);
				}
				productModel.setLineNumber(number);
				// 计算皮重
				BigDecimal tare = getProductTare(productModel);
				productModel.setTare(tare);
				productModel.setProId(UUID.randomUUID().toString());
				productModel.setDraId(contractVOModel.getDraId());
				productModel.setStatus(contractVOModel.getStatus());
				productDao.insert(productModel);
			}
		}
		if (result > 0) {
			httpResult.setMsg(contractVOModel.getStatus().equals(Global.YES + "") ? "提交成功!" : "保存成功!");
			httpResult.setData(contractVOModel);
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg(contractVOModel.getStatus().equals(Global.YES + "") ? "提交失败!" : "保存失败!");
		}
		return httpResult;
	}

	// 计算产品的皮重
	private BigDecimal getProductTare(ProductModel productModel) {
		BigDecimal tare = BigDecimal.valueOf(0);
		String masterNum = productModel.getSkuNum();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("skuNum", masterNum);
		// 根据masterNum 查询所属的全部itemSku
		List<SkuItemModel> itemSkus = skuItemDao.selectList(params);
		if (itemSkus != null && !itemSkus.isEmpty()) {

			for (int i = 0; i < itemSkus.size(); i++) {
				SkuItemModel skuItemModel = itemSkus.get(i);

				if ("V".equals(skuItemModel.getItemType())) {
					// sku包材比例
					String skuitemCount = skuItemModel.getItemCount();
					String mmCode = skuItemModel.getItemNum();
					MmModel mm = mmDao.load(mmCode);
					if (mm != null) {
						// 物料主数据的包材净重
						String suttle = org.apache.commons.lang3.StringUtils.isNotBlank(mm.getSuttle()) ? mm.getSuttle()
								: "0";
						// 判断是否为小数
						if (skuitemCount.contains(".")) {
							// 小数想上取整
							skuitemCount = String.valueOf(Math.ceil(Double.valueOf(skuitemCount)));
						}
						// 包材净重* sku比例
						BigDecimal temp = new BigDecimal(suttle).multiply(new BigDecimal(skuitemCount));
						tare.add(temp);
					}
				}
			}
			// 包材净重* sku比例*包装数量
			tare.multiply(productModel.getDraNum());
		}
		return tare;
	}

	/**
	 * 删除
	 *
	 * @param
	 * @return
	 */
	public HttpResult delete(String draId) {
		HttpResult httpResult = new HttpResult();
		if (!StringUtils.isNotNull(draId)) {
			return HttpResult.error("参数不能为空");
		}
		int result = contractDraftDao.delete(draId);
		if (result > 0) {
			httpResult.setMsg("删除成功！");
		} else {
			httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
			httpResult.setMsg("不存在此条数据！");
		}
		return httpResult;
	}

	/**
	 * 导出
	 *
	 * @param queryMap
	 * @param response
	 */
	public void export(Map<String, Object> queryMap, HttpServletResponse response) {
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (!sysUser.getSuperadmin().equals(Global.YES + "")) {
			if (StringUtils.isNotNull(sysUser.getDatapermission())) {
				queryMap.put("deptIds", sysUser.getDatapermission().split(","));
			} else {
				if (sysUser.getBtnPermission() != null
						&& sysUser.getBtnPermission().contains(BtnDbPermissionEnum.sale.getValue())) {
					// 销售管理员
				} else if (sysUser.getBtnPermission() != null
						&& sysUser.getBtnPermission().contains(BtnDbPermissionEnum.BatteryChemical.getValue())) {
					// 锂电池管理员
					queryMap.put("draOrgName", BtnDbPermissionEnum.BatteryChemical.getName());
					queryMap.put("dracreateId", sysUser.getUserid());
				} else if (sysUser.getBtnPermission() != null
						&& sysUser.getBtnPermission().contains(BtnDbPermissionEnum.FineChemical.getValue())) {
					// 精细管理员
					queryMap.put("draOrgName", BtnDbPermissionEnum.FineChemical.getName());
					queryMap.put("dracreateId", sysUser.getUserid());
				} else if (StringUtils.isNotNull(sysUser.getDatapermission())) {
					// 销售部门权限
					queryMap.put("deptIds", sysUser.getDatapermission().split(","));
				} else {
					queryMap.put("createId", sysUser.getUserid());
				}
			}
		}
		List<ContractDraftModel> list = contractDraftDao.selectList(queryMap);
		logger.info("export:{}", list);
		try {
			EasyExcel.write(response.getOutputStream(), ContractDraftModel.class).sheet("模板").doWrite(list);
		} catch (IOException e) {
			logger.error("导出错误:{}", e.getMessage());
		}

	}

	/**
	 * 合同起草撤回
	 */
	@Transactional
	public HttpResult back(ContractVOModel contractVOModel) {
		if (contractVOModel == null) {
			return HttpResult.error("请求参数不能为空!");
		}
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(contractVOModel.getOaWfId() + "")) {
			// oa退回才可撤回
			HttpResult httpResult = wfStatusService.getWorkflowRequestLogs(sysUser.getWxid(),
					WorkFlowIdModel.saleContractString, contractVOModel.getOaWfId() + "");
			if (httpResult.getCode() != HttpStatus.SUCCESS_CODE) {
				return httpResult;
			}
		}
		HashMap<String, Object> hashMap = new HashMap();
		hashMap.put("ordId", contractVOModel.getDraId());
		List<ContractSignModel> list = contractSignDao.loadSignListByDraId(contractVOModel.getDraId());
		if (list != null && list.size() > 0) {
			return HttpResult.error("请先在合同签署删除该合同！");
		}

		int result = 0;
		contractVOModel.setTransedSap(Global.NO + "");
		contractVOModel.setStatus(Global.NO + "");
		result = contractDraftDao.update(contractVOModel);
		if (result > 0) {
			return HttpResult.ok("回退成功");
		} else {
			return HttpResult.error("不存在此合同！");
		}
	}

	/**
	 * 长约合同起草撤回
	 */
	public HttpResult backLongTerm(ContractVOModel contractVOModel) {
		if (contractVOModel == null) {
			return HttpResult.error("请求参数不能为空!");
		}
		SysUser sysUser = SpringMvcUtils.getSysUser();
		if (StringUtils.isNotNull(contractVOModel.getOaWfId() + "")) {
			// oa退回才可撤回
			HttpResult httpResult = wfStatusService.getWorkflowRequestLogs(sysUser.getWxid(),
					WorkFlowIdModel.longSaleContractString, contractVOModel.getOaWfId() + "");
			if (httpResult.getCode() != HttpStatus.SUCCESS_CODE) {
				return httpResult;
			}
		}
		HashMap<String, Object> hashMap = new HashMap();
		hashMap.put("ordId", contractVOModel.getDraId());
		List<ContractSignModel> list = contractSignDao.loadSignListByDraId(contractVOModel.getDraId());
		if (list != null && list.size() > 0) {
			return HttpResult.error("请先在合同签署删除该合同！");
		}

		int result = 0;
		contractVOModel.setTransedSap(Global.NO + "");
		contractVOModel.setStatus(Global.NO + "");
		result = contractDraftDao.update(contractVOModel);
		if (result > 0) {
			return HttpResult.ok("回退成功");
		} else {
			return HttpResult.error("不存在此合同！");
		}
	}

	private String createDraftSerialNumber() {
		// 取得当前年份后两位
		SimpleDateFormat sdf = new SimpleDateFormat("yy");
		Date date = new Date();
		String year = sdf.format(date);
		// 获取本年内发起的合同总数（包括已删除的）
		int count = contractDraftDao.selectListCountAll();
		AtomicInteger atomicInteger = new AtomicInteger(000000);

		// 2022年编号比较混乱.从2023年开始，合同号从000000开始累加，此处对2022年做特殊处理
		if ("22".equals(year)) {
			atomicInteger = new AtomicInteger(950000);
		}

		// 将count与atomicInteger的初始值相加
		atomicInteger.addAndGet(count);
		// 合同号总数加一
		int num = atomicInteger.incrementAndGet();
		// 补0
		DecimalFormat decimalFormat = new DecimalFormat("000000");
		String serNum = decimalFormat.format(num);
		return "SC" + year + serNum;

	}

}
